package com.ktjiaoyu.utils;

import com.ktjiaoyu.common.CodeConstant;

import java.io.Serial;
import java.io.Serializable;

/**
 * @version 1.0
 * @ClassName R
 * @Description 响应结果封装类
 * @Author NanJi
 * @Date 2025/3/31 : 8:57
 */

public final class R<T> implements Serializable {
    @Serial
    private static final long serialVersionUID = 1L;

    private final int code;
    private final String msg;
    private final T data;

    /**
     * 私有构造器，使用工厂方法创建实例
     *
     * @param builder 建造者对象
     */
    private R(Builder<T> builder) {
        this.code = builder.code;
        this.msg = builder.msg;
        this.data = builder.data;
    }

    /**
     * 建造者类
     *
     * @param <T> 数据类型
     */
    public static class Builder<T> {
        private int code;
        private String msg;
        private T data;

        public Builder() {
        }

        public Builder<T> code(int code) {
            this.code = code;
            return this;
        }

        public Builder<T> msg(String msg) {
            this.msg = msg;
            return this;
        }

        public Builder<T> data(T data) {
            this.data = data;
            return this;
        }

        public R<T> build() {
            return new R<>(this);
        }
    }


    /**
     * 成功返回-工厂方法
     *
     * @param <T> 数据类型
     * @return R实例
     */
    public static <T> R<T> ok() {
        return ok(null);
    }

    public static <T> R<T> ok(T data) {
        return new Builder<T>()
                .code(CodeConstant.SUCCESS.getCode())
                .msg(CodeConstant.SUCCESS.getMessage())
                .data(data)
                .build();
    }

    public static <T> R<T> ok(String msg) {
        return new Builder<T>()
                .code(CodeConstant.SUCCESS.getCode())
                .msg(msg)
                .data(null)
                .build();
    }

    public static <T> R<T> ok(int code, String msg, T data) {
        return new Builder<T>()
                .code(code)
                .msg(msg)
                .data(data)
                .build();
    }

    /**
     * 失败返回-工厂方法
     *
     * @param <T> 数据类型
     * @return R实例
     */
    public static <T> R<T> fail() {
        return fail(null);
    }

    public static <T> R<T> fail(T data) {
        return new Builder<T>()
                .code(CodeConstant.FAIL.getCode())
                .msg(CodeConstant.FAIL.getMessage())
                .data(data)
                .build();
    }

    public static <T> R<T> fail(String msg) {
        return new Builder<T>()
                .code(CodeConstant.FAIL.getCode())
                .msg(CodeConstant.FAIL.getMessage())
                .data(null)
                .build();
    }

    public static <T> R<T> fail(int code, String msg, T data) {
        return new Builder<T>()
                .code(code)
                .msg(msg)
                .data(data)
                .build();
    }

    /**
     * 自定义错误返回-工厂方法
     *
     * @param code 状态码
     * @param msg  消息
     * @param <T>  数据类型
     * @return R实例
     */
    public static <T> R<T> error(int code, String msg) {
        return error(code, msg, null);
    }

    public static <T> R<T> error(int code, String msg, T data) {
        return new Builder<T>()
                .code(code)
                .msg(msg)
                .data(data)
                .build();
    }

    // Getter方法
    public int getCode() {
        return code;
    }

    public String getMsg() {
        return msg;
    }

    public T getData() {
        return data;
    }

    // 是否成功
    public boolean isSuccess() {
        return code == CodeConstant.SUCCESS.getCode();
    }

    // 是否失败
    public boolean isFail() {
        return !isSuccess();
    }

    // 重写toString方法
    @Override
    public String toString() {
        return "R_v2{" +
                "code=" + code +
                ", msg='" + msg + '\'' +
                ", data=" + data +
                '}';
    }
}
